package com.zzyl.serve.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.serve.domain.NursingPlan;
import com.zzyl.serve.domain.NursingProjectPlan;
import com.zzyl.serve.dto.NursingPlanDto;
import com.zzyl.serve.mapper.NursingPlanMapper;
import com.zzyl.serve.service.INursingPlanService;
import com.zzyl.serve.service.INursingProjectPlanService;
import com.zzyl.serve.vo.NursingPlanVo;
import com.zzyl.serve.vo.NursingProjectPlanVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 护理计划Service业务层处理
 * 
 * @author mr.wu
 * @date 2025-05-15
 */
@Service
public class NursingPlanServiceImpl extends ServiceImpl<NursingPlanMapper,NursingPlan>  implements INursingPlanService
{
    @Autowired
    private NursingPlanMapper nursingPlanMapper;

    /**
     * 查询全部护理计划列表
     *
     * @return
     */
    @Override
    public List<NursingPlanVo> getAll() {
        List<NursingPlan> nursingPlanList = this.lambdaQuery().select(NursingPlan::getPlanName,NursingPlan::getId).eq(NursingPlan::getStatus, 1).list();
        List<NursingPlanVo> voList = nursingPlanList.stream().map(x -> {
            NursingPlanVo vo = new NursingPlanVo();
            vo.setLabel(x.getPlanName());
            vo.setValue(x.getId().intValue());
            return vo;
        }).collect(Collectors.toList());
        return voList;
    }

    /**
     * 查询护理计划
     * 
     * @param id 护理计划主键
     * @return 护理计划
     */
    @Override
    public NursingPlanVo selectNursingPlanById(Long id)
    {
        NursingPlanVo vo = new NursingPlanVo();
        //1. 根据ID查询护理计划
        NursingPlan plan = this.getById(id);
        BeanUtils.copyProperties(plan,vo);

        //2. 查询关联的关系数据列表  select * from nuring_project_plan where plan_id=?
        List<NursingProjectPlan> nursingProjectPlans = nursingProjectPlanService.lambdaQuery()
                .eq(NursingProjectPlan::getPlanId, id).list();
        List<NursingProjectPlanVo> ppVoList = nursingProjectPlans.stream().map(pp -> {
            NursingProjectPlanVo ppVo = new NursingProjectPlanVo();
            ppVo.setId(String.valueOf(pp.getId()));
            ppVo.setPlanId(String.valueOf(pp.getPlanId()));
            ppVo.setProjectId(String.valueOf(pp.getProjectId()));
            ppVo.setExecuteTime(String.valueOf(pp.getExecuteTime()));
            ppVo.setExecuteFrequency(String.valueOf(pp.getExecuteFrequency()));
            ppVo.setExecuteCycle(String.valueOf(pp.getExecuteCycle()));
            return ppVo;
        }).collect(Collectors.toList());

        //3. 组装数据
        vo.setProjectPlans(ppVoList);
        return vo;
    }

    /**
     * 查询护理计划列表
     * 
     * @param nursingPlan 护理计划
     * @return 护理计划
     */
    @Override
    public List<NursingPlan> selectNursingPlanList(NursingPlan nursingPlan)
    {
        return nursingPlanMapper.selectNursingPlanList(nursingPlan);
    }

    @Autowired
    private INursingProjectPlanService nursingProjectPlanService;

    /**
     * 新增护理计划
     * 
     * @param dto 护理计划
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertNursingPlan(NursingPlanDto dto)
    {
        NursingPlan plan = new NursingPlan();
        //copyProperties的作用：复制源对象的属性给目标对象
        BeanUtils.copyProperties(dto, plan);

        //1. 保存护理计划
        boolean resultPlan = this.save(plan);
        if(!resultPlan) {
            throw new BaseException("保存护理计划失败");
        }

        //2. 批量保存护理计划和护理项目的关系数据
        List<NursingProjectPlan> projectPlanList = dto.getProjectPlans();
        projectPlanList.forEach(x->{
            x.setPlanId(plan.getId());//设置护理计划主键id
        });
        boolean resultPP = nursingProjectPlanService.saveBatch(projectPlanList);
        if(!resultPP) {
            throw new BaseException("保存护理计划和护理项目的关系数据失败");
        }

        return 1;
    }

    /**
     * 修改护理计划
     * 
     * @param dto 护理计划
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateNursingPlan(NursingPlanDto dto)
    {
        //0. 基础校验：判断护理计划是否存在  select count(*) from nursing_plan where id=?
        Long count = this.lambdaQuery().eq(NursingPlan::getId, dto.getId()).count();
        if(count<1){
            throw new BaseException("数据不存在无法更新");
        }

        NursingPlan plan = new NursingPlan();
        BeanUtils.copyProperties(dto, plan);

        //1. 更新护理计划信息
        boolean planResult = this.updateById(plan);
        if(!planResult) {
            throw new BaseException("更新护理计划信息失败");
        }

        //2. 删除旧的护理项目和护理计划的关系数据 delete from nursing_project_plan where plan_id=?
        nursingProjectPlanService.remove(Wrappers.<NursingProjectPlan>lambdaQuery().eq(NursingProjectPlan::getPlanId, dto.getId()));

        //3. 更新护理项目和护理计划的关系数据
        List<NursingProjectPlan> projectPlanList = dto.getProjectPlans();
        if(CollUtil.isNotEmpty(projectPlanList)) {
            projectPlanList.forEach(x->{
                x.setPlanId(plan.getId());//设置护理计划主键id
            });
            boolean resultPP = nursingProjectPlanService.saveBatch(projectPlanList);
            if(!resultPP) {
                throw new BaseException("保存护理计划和护理项目的关系数据失败");
            }
        }

        return 1;
    }

    /**
     * 批量删除护理计划
     * 
     * @param ids 需要删除的护理计划主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteNursingPlanByIds(Long[] ids)
    {
        if(ids==null || ids.length==0) {
            throw new BaseException("参数为空");
        }

        //1. 基础校验：判断对应的护理计划是否存在
        for (Long id : ids) {
            Long count = this.lambdaQuery().eq(NursingPlan::getId, id).count();
            if(count<1){
                throw new BaseException("数据不存在无法更新");
            }
        }

        //2. 批量删除每个护理计划对应的关系数据
        for (Long id : ids) {
            nursingProjectPlanService.remove(Wrappers.<NursingProjectPlan>lambdaQuery().eq(NursingProjectPlan::getPlanId, id));
        }

        //3. 批量删除护理计划
        return this.removeByIds(Arrays.asList(ids)) ? ids.length : 0;
    }

    /**
     * 删除护理计划信息
     * 
     * @param id 护理计划主键
     * @return 结果
     */
    @Override
    public int deleteNursingPlanById(Long id)
    {
        return this.removeById(id) ? 1 : 0;
    }
}
